package server.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import message.RpcRequestMessage;
import message.RpcResponseMessage;
import server.factory.ServicesFactory;

import java.lang.reflect.Method;

/**
 * @author David
 */
@Slf4j
@ChannelHandler.Sharable
public class RpcRequestMessageHandler extends SimpleChannelInboundHandler<RpcRequestMessage> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequestMessage message) throws ClassNotFoundException {
        RpcResponseMessage response = new RpcResponseMessage();
        response.setSequenceId(message.getSequenceId());

        // 这儿是根据传入的接口方法名来找到对应实现，利用反射的方法调用
        try {
            Object service = ServicesFactory.getService(message.getInterfaceName());
            if(service == null){
                response.setExceptionValue(new Exception("远程无此服务"));
            }else{
                Method method = service.getClass().getMethod(message.getMethodName(), message.getParameterTypes());
                Object invoke = method.invoke(service, message.getParameterValue());

                response.setReturnValue(invoke);
            }

        } catch (Exception e) {
            e.printStackTrace();
            String msg = e.getCause().getMessage();
            response.setExceptionValue(new Exception("远程调用出错:" + msg));
        }

        ctx.writeAndFlush(response);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event = (IdleStateEvent) evt;
        if(event.state() == IdleState.READER_IDLE){
            log.info("超过60s未检测到连接，将关闭此channel...");
            ctx.channel().writeAndFlush("您的连接已经超时");
            ctx.channel().close();
        }
    }
}
